<?php
namespace Tlf\BigDb\Test;
class BigDbServer extends \Tlf\Tester {
public function prepare(){
require_once($this->file('test/input/BigDbApp/ArticleDb.php'));
require_once($this->file('test/input/BigDbApp/orm/Article.php'));
require_once($this->file('test/input/BigDbApp/orm/Author.php'));
require_once($this->file('test/input/BigDbApp/orm/Tag.php'));
require_once($this->file('test/input/BigDbTasks/TasksDb.php'));
require_once($this->file('test/input/BigDbTasks/orm/Task.php'));
// require_once($this->file('test/input/BigDbApp/orm/Author.php'));
// require_once($this->file('test/input/BigDbApp/orm/Tag.php'));
}
public function testAccess(){
// I decided to disable this test, because I can't figure out how to integrate access into this system.
// I WANT it, but upon further thought (see my commented notes below), I don't think access really belongs within the db layer.
// The DB should not know or care about users & access. That's the application's job, typically during route resolution AFTER loading items from the database.
// The PROBLEM with this is ... I KNOW access is an important part of any public-facing system, and I want to provide a solution for this.
// I just don't know how to do it in a reasonable way.
// So, I'm going to call it, start using it, and probably come back to this access question later.
$this->disable();
return;
$pdo = $this->getPdo();
$art = new \Tlf\BigDb\Test\ArticlesDb($pdo);
$server = new \Tlf\BigDbServer();
// $server->addDatabase(Tlf\BigDb\Test\ArticlesDb::class);
$server->addDatabase(new \Tlf\BigDb\Test\ArticlesDb($pdo));
$server->addDatabase(new \Tlf\BigDb\Test\TasksDb($pdo));
$server->tasks->addSqlDir($this->file('test/input/BigDbServer/TaskSql'), true);
$server->tasks->recompile_sql();
$server->tasks->migrate(0,1);
// example situation:
// A user tries to view an article that is private
// access is denied because the user is not the author or an admin
//
// Access Layers:
// On the orm: If active user is the author, access is granted.
// authorship is specific to articles
// On the database layer: If article is public, access is granted.
// public/private is used across all (or most) tables in this db library
// On the bigdb server layer: Access is granted if user is an admin, regardless of lower-level checks
//
// so,
// the point of an access layer is to control which USERs have access to data. This is not inherint to a db structure
// but rather is about the needs & desires of the website.
// The ORM should not be deciding who has access to it, because the orm should typically have no concept of users
// An article knows about authors, but should not know about the abstract concept of a user.
// The webserver needs to understand the relationship beetween an author and a user, because the webserver integrates the two.
//
// So what role can the BigDb layer play? What awareness should a database layer have? It should know about its own ORMs, queries, migrations. It should not know about the broader system, and it should know nothing of usership.
//
// BigDb is responsible for loading data from the database. It, I think, should allow some kind of extensibility/integration for access controls.
// So, it should essentially ask the system (which it's not informed about) if THIS ROW can be returned, or INSERTED, or whatever.
//
//
// This is all too abstract. I need a more concrete example.
// /article/{slug}/ is requested.
// a Private Article is loaded from database.
// The user is NOT an admin, NOR the author
// Access is denied <-- Q1: Where does THIS happen
// An error page is displayed.
//
// Q1: within the route-code.
// The route will check
// if author == cur_user
// OR if cur_user == admin
// OR if article.status == public
}
public function testBigDbServer(){
$pdo = $this->getPdo();
$art = new \Tlf\BigDb\Test\ArticlesDb($pdo);
$server = new \Tlf\BigDbServer();
// $server->addDatabase(Tlf\BigDb\Test\ArticlesDb::class);
$server->addDatabase(new \Tlf\BigDb\Test\ArticlesDb($pdo));
$server->addDatabase(new \Tlf\BigDb\Test\TasksDb($pdo));
$server->tasks->addSqlDir($this->file('test/input/BigDbServer/TaskSql'), true);
$server->tasks->recompile_sql();
$server->tasks->migrate(0,1);
$this->test("Migrate, sql, and query_rows work for TasksDb added to BigDbServer");
$tasks = $server->tasks->query_rows('task.get_overdue');
$task_titles = array_map(function($row){return $row['title'];}, $tasks);
$this->compare_arrays(
['Jog', 'Walk', 'Read'],
$task_titles
);
$this->test("SQL Query for incomplete future tasks.");
$tasks = $server->tasks->sql_query('SELECT `title` FROM `task` WHERE `due_date` > CURRENT_TIMESTAMP AND `date_completed` IS NOT NULL');
$this->compare_arrays(
[0=>['title'=>'Get Cleaning Supplies'],
1=>['title'=>'Buy Shoes']
],
$tasks
);
$this->test("User supplied stored sql works");
$stored_tasks = $server->tasks->query_rows('task.get_incomplete_future_tasks');
$this->compare_arrays(
$tasks,
$stored_tasks
);
###
// Add user-defined access settings
// then test both allowing & denying access to some rows.
}
}